package com.myk.game.gobangchess.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class GridsUtils {

    /**
     * 棋盘格子的二维数组转为字符串，行用"r"来分割，纵用"c"来分割
     */
    public static String grids2Str(int[][] grids) {
        int row = grids.length;
        int col = grids[0].length;
        String gridStr = "";
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                String tempStr = String.valueOf(grids[i][j]);
                if (j < col - 1) {
                    tempStr += "c";
                }
                gridStr += tempStr;
            }
            if (i < row - 1) {
                gridStr += "r";
            }
        }
        return gridStr;
    }

    /**
     * 以格式化方式输出棋盘
     */
    public static String formatGrids(int[][] grids) {
        int row = grids.length;
        int col = grids[0].length;
        StringBuilder gridStr = new StringBuilder();
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                String tempStr = String.valueOf(grids[i][j]);
                gridStr.append(tempStr);
                gridStr.append(" ");
            }
            gridStr.append("\n");
        }
        return gridStr.toString();
    }

/*    public static void main(String[] args) {
        System.out.println(formatGrids(BoardStyleData.FOUR_GRAVITE_STYLE_6x10));
    }*/

    /**
     * 将代表棋盘格子的字符串数据转为二维数组形式
     */
    public static int[][] str2Grids(String gridsStr) {
        String[] rows = gridsStr.split("r");
        int row = rows.length;
        String[] firstCols = rows[0].split("c");
        int col = firstCols.length;
        int[][] gridsArr = new int[row][col];
        for (int i = 0; i < row; i++) {
            String[] cols = rows[i].split("c");
            for (int j = 0; j < col; j++) {
                gridsArr[i][j] = Integer.parseInt(cols[j]);
            }
        }
        return gridsArr;
    }

    /**
     * 拷贝二维数组，通过for循环遍历
     */
    public static int[][] copyGrids(int[][] grids) {
        int row = grids.length;
        int col = grids[0].length;
        int[][] newGrids = new int[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                newGrids[i][j] = grids[i][j];
            }
        }
        return newGrids;
    }

    /**
     * 创建指定大小的空棋盘
     */
    public static int[][] createEmptyGrids(int row, int col) {
        int[][] newGrids = new int[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                newGrids[i][j] = 0;
            }
        }
        return newGrids;
    }

    /**
     * 根据指定图片创建棋盘格子数组，有颜色的填上黑色格子
     */
    public static int[][] createGridsByImage(String filePath,int row, int col){
        int[][] newGrids = GridsUtils.createEmptyGrids(row, col); //创建默认的空数组
        try {
            File imageFile = new File(filePath); //获取图片文件
            if (!imageFile.exists()) return newGrids; //判断图片文件是否存在
            BufferedImage image = ImageIO.read(imageFile); //获取图片
            BufferedImage newImage = new BufferedImage(col, row, BufferedImage.TYPE_INT_ARGB); //压缩图片到指定大小
            Graphics2D gr = newImage.createGraphics();
            gr.drawImage(image, 0, 0, col, row, null);
            gr.dispose();
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    int rgb = newImage.getRGB(j, i);
                    int alpha = (rgb >> 24) & 0xFF;
                    if (alpha > 0) {
                        newGrids[i][j] = 1;
                    }
                }
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return newGrids;
    }

    /**
     * 填充数组（左上角重叠）
     */
    public static void fillGrids(int[][] source, int[][] target) {
        int sRow = source.length;
        int sCol = source[0].length;
        int tRow = target.length;
        int tCol = target[0].length;
        int row = Math.min(sRow, tRow);
        int col = Math.min(sCol, tCol);
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                target[i][j] = source[i][j];
            }
        }
    }

    /**
     * 范围格子随机筑一堵墙方法
     *
     * @param from    起点（左上角）
     * @param to      终点（右下角）
     * @param excepts 不能筑墙的格子
     * @return
     */
    public static Point gridsBuildWall(Point from, Point to, Point... excepts) {
        int x = (int) (Math.random() * (to.x - from.x) + from.x);
        int y = (int) (Math.random() * (to.y - from.y) + from.y);

        for (Point except : excepts) {
            if (except != null && except.x == x && except.y == y) {
                return gridsBuildWall(from, to, excepts);
            }
        }
        return new Point(x, y);
    }

    /**
     * 获取grids中数据为param的数量
     */
    public static int getDataCount(int[][] grids, int... params) {
        int count = 0;

        int row = grids.length;
        int col = grids[0].length;
        int mar = params.length;

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                for (int k = 0; k < mar; k++) {
                    if (grids[i][j] == params[k]) {
                        count++;
                    }
                }
            }
        }

        return count;
    }

    /**
     * 判断给定坐标是否在grids范围内
     */
    public static boolean isInGrids(int[][] curGrids, int row, int col) {
        if (curGrids == null) {
            return false;
        } else {
            int h = curGrids.length;
            int w = curGrids[0].length;
            return row >= 0 && row < h && col >= 0 && col < w;
        }
    }

    /**
     * 获取两点之间连线所有格子坐标 (不在一条直线上的也会尽量平滑的获取)
     */
    public static List<int[]> getLineGridsBetweenPoints(int x0, int y0, int x1, int y1) {
        List<int[]> grids = new ArrayList<>();
        int dx = Math.abs(x1 - x0);
        int dy = -Math.abs(y1 - y0); // 注意dy取负数
        int sx = x0 < x1 ? 1 : -1;
        int sy = y0 < y1 ? 1 : -1;
        int err = dx + dy;

        while (true) {
            grids.add(new int[]{x0, y0});
            if (x0 == x1 && y0 == y1) break;
            int e2 = 2 * err;

            if (e2 >= dy) { // 水平移动优先
                err += dy;
                x0 += sx;
            }
            if (e2 <= dx) { // 垂直移动补偿
                err += dx;
                y0 += sy;
            }
        }
        return grids;
    }

    /**
     * 获取两点之间形成的矩形的所有格子坐标-先从上到下再从左到右
     */
    public static List<int[]> getRectGridsBetweenPointsUp(int x1, int y1, int x2, int y2) {
        List<int[]> grids = new ArrayList<>();
        int xMin = Math.min(x1, x2);
        int xMax = Math.max(x1, x2);
        int yMin = Math.min(y1, y2);
        int yMax = Math.max(y1, y2);

        // 确定遍历方向：以第一个点 (x1,y1) 为起点顺序遍历
        boolean xDirection = (x1 <= x2); // true从左到右，false从右到左
        boolean yDirection = (y1 <= y2); // true从上到下，false从下到上

        // 按行优先顺序遍历
        if (yDirection) {
            for (int y = yMin; y <= yMax; y++) {
                if (xDirection) {
                    for (int x = xMin; x <= xMax; x++) {
                        grids.add(new int[]{x, y});
                    }
                } else {
                    for (int x = xMax; x >= xMin; x--) {
                        grids.add(new int[]{x, y});
                    }
                }
            }
        } else {
            for (int y = yMax; y >= yMin; y--) {
                if (xDirection) {
                    for (int x = xMin; x <= xMax; x++) {
                        grids.add(new int[]{x, y});
                    }
                } else {
                    for (int x = xMax; x >= xMin; x--) {
                        grids.add(new int[]{x, y});
                    }
                }
            }
        }
        return grids;
    }

    /**
     * 获取两点之间形成的矩形所有格子坐标-先从左到右再从上到下
     */
    public static List<int[]> getRectGridsBetweenPointsRight(int x1, int y1, int x2, int y2) {
        List<int[]> grids = new ArrayList<>();
        int xMin = Math.min(x1, x2);
        int xMax = Math.max(x1, x2);
        int yMin = Math.min(y1, y2);
        int yMax = Math.max(y1, y2);

        // 确定遍历方向：以第一个点 (x1,y1) 为起点顺序遍历
        boolean xDirection = (x1 <= x2); // true从左到右，false从右到左
        boolean yDirection = (y1 <= y2); // true从上到下，false从下到上

        // 列优先遍历（从左到右，再从上到下）
        if (xDirection) {
            for (int x = xMin; x <= xMax; x++) {
                if (yDirection) {
                    for (int y = yMin; y <= yMax; y++) {
                        grids.add(new int[]{x, y});
                    }
                } else {
                    for (int y = yMax; y >= yMin; y--) {
                        grids.add(new int[]{x, y});
                    }
                }
            }
        } else {
            for (int x = xMax; x >= xMin; x--) {
                if (yDirection) {
                    for (int y = yMin; y <= yMax; y++) {
                        grids.add(new int[]{x, y});
                    }
                } else {
                    for (int y = yMax; y >= yMin; y--) {
                        grids.add(new int[]{x, y});
                    }
                }
            }
        }
        return grids;
    }
}
